from PyQt5.QtCore import Qt, QSize, QThread, QMutex, pyqtSignal, QObject, QTimer
from PyQt5.QtGui import QFontDatabase, QFont, QIcon
from PyQt5.QtWidgets import QWidget, QListWidget, QStackedWidget, QHBoxLayout,\
    QListWidgetItem, QMessageBox
from shopWidget import shopWidget
from monitorWidget import ClientUI
from activityWidget import activityWidget
from LandWidget import LandWidget
from LginDialog import LoginDialog
from orderWidget import orderWidget
from advertiseWidget import advertiseWidget
from Dialog import WarningMessageBox, QuestionMessageBox, LoadingDialog
from handler.leasedLandHandle import LeaseLandHandle
from handler.goodsHandle import goodsHandle
from handler.activityHandle import activityHandle
from handler.orderHandle import orderHandle
from handler.envDataHandle import envDataHandle
import cv2
import time
import ctypes
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
# f03d 摄像头
# f217 购物车
# f196 添加
# f007 用户名
# f13e 密码
# 11, 74, 126

devices_info = [{
    'deviceId': 0,
    'dataDeviceId': '262041615237',
    'rtmp_addr': "rtmp://af1.yunchuanglive.com/live/44030700020200827001",
    'deviceName': '一号相机',
    'deviceCategory': '鸡舍'
},
{
    'deviceId': 1,
    'dataDeviceId': '262041615237',
    'rtmp_addr': "rtmp://af1.yunchuanglive.com/live/44030700020200827002",
    'deviceName': "二号相机",
    'deviceCategory': '花园'
},
{
    'deviceId': 2,
    'dataDeviceId': '262041615237',
    'rtmp_addr': "rtmp://af1.yunchuanglive.com/live/44030700020200827003",
    'deviceName': "三号相机",
    'deviceCategory': "竹林"
},
{
    'deviceId': 3,
    'dataDeviceId': '262041615237',
    'rtmp_addr': "rtmp://af1.yunchuanglive.com/live/44030700020200827004",
    'deviceName': "四号相机",
    'deviceCategory': "鸭塘"
}]

class disPlayData:
    def __init__(self):
        self.timex = []
        self.tempy = []
        self.humidity = []
        self.PM2D5 = []
        self.lighty = []

mux = QMutex()

class getCapture(QObject):
    ok = pyqtSignal(list)

    def __init__(self, parent=None):
        super(getCapture, self).__init__(parent)

    def getRtmpCap(self, source):
        cap = cv2.VideoCapture(source)
        self.ok.emit([cap, ])

class showVideo(QObject):
    getImg = pyqtSignal(list)
    imgError = pyqtSignal()

    def __init__(self, parent=None):
        super(showVideo, self).__init__(parent=parent)
        self._cap = None
        self._runFlag = False
        self.list = list()

    def showImg(self):
        while self._runFlag:
            if self._cap is not None:
                try:
                    ret, img = self._cap.read()
                except:
                    break
                if ret:
                    self.list.append(img)
                    self.getImg.emit(self.list)
                    self.list.clear()
                else:
                    self._cap = None
                    self.imgError.emit()
            else:
                time.sleep(1)

    def stop(self):
        mux.lock()
        self._runFlag = False
        mux.unlock()

    def start(self):
        mux.lock()
        self._runFlag = True
        mux.unlock()
        self.showImg()

    def setCap(self, cap):
        self._cap = cap[0]
        self.start()

class LeftTabWidget(QWidget):
    changeAddr = pyqtSignal(str)
    setCap = pyqtSignal(list)

    def __init__(self, *args, **kwargs):
        super(LeftTabWidget, self).__init__(*args, **kwargs)
        self.landHandler = LeaseLandHandle()
        self._goodsHandler = goodsHandle()
        self._activityHandler = activityHandle()
        self._orderHandler = orderHandle()
        self._envDataHandle = envDataHandle()
        self._displayFlag = [0, 1, 1, 1, 1]
        self._deviceMsg = None

        layout = QHBoxLayout(self, spacing=0)
        layout.setContentsMargins(0, 0, 0, 0)

        self._rmtpMap = dict()
        self._capMap = dict()
        self._currentCapName = None
        self._initDeviceMsg()
        self._deviceMsg = devices_info

        self.waitDia = LoadingDialog()
        self._listWidget = QListWidget(self)
        layout.addWidget(self._listWidget)
        self._stackedWidget = QStackedWidget(self)
        layout.addWidget(self._stackedWidget)
        self.setLayout(layout)
        self._monitor = ClientUI()
        self._advertiseWidget = advertiseWidget()
        self._shopWidget = shopWidget()
        self._activityWidget = activityWidget()
        self._orderItemDisPlayWidget = orderWidget()
        self._landWidget = LandWidget()

        self.addWidget(self._monitor)
        self.addWidget(self._advertiseWidget)
        self.addWidget(self._shopWidget)
        self.addWidget(self._activityWidget)
        self.addWidget(self._landWidget)
        self.addWidget(self._orderItemDisPlayWidget)
        self._addItem("\uf03d")
        self._addItem("\uf028")
        self._addItem("\uf217")
        self._addItem("\uf0c0")
        self._addItem("\uf2a1")
        self._addItem("\uf1ea")
        self._initListWidget()
        # 默认选择第一个
        item = self._listWidget.item(0)
        self._listWidget.setCurrentItem(item)

        self._connectSlots()
        # 最大化显示
        windowIcon = QIcon("../Data/logo.ico")
        self.setWindowIcon(windowIcon)
        self.showMaximized()

        self._initShowVideoModel()
        self._initGetCapModel()
        self.setWindowTitle("一线生鸡")

    def _initDeviceMsg(self):
        self._rmtpMap["一号相机"] = "rtmp://af1.yunchuanglive.com/live/44030700020200827001"
        self._rmtpMap["二号相机"] = "rtmp://af1.yunchuanglive.com/live/44030700020200827002"
        self._rmtpMap["三号相机"] = "rtmp://af1.yunchuanglive.com/live/44030700020200827003"
        self._rmtpMap["四号相机"] = "rtmp://af1.yunchuanglive.com/live/44030700020200827004"

    def _initGetCapModel(self):
        self.getCap = getCapture()
        self.imgThread = QThread()
        self.getCap.moveToThread(self.imgThread)
        self.changeAddr.connect(self.getCap.getRtmpCap)
        self.imgThread.start()
        self.getCap.ok.connect(self.waitDia.accept)
        self.getCap.ok.connect(self._getCap)
        self.setCap.connect(self.showVideo.setCap)

    def _initShowVideoModel(self):
        self.showVideo = showVideo()
        self.showVideo.getImg.connect(self._monitor.displayVideo)
        self.showVideo.imgError.connect(self._getImgError)
        self.showVideoThread = QThread()
        self.showVideo.moveToThread(self.showVideoThread)
        self.showVideoThread.start()

    def _connectSlots(self):
        self._monitor.ListWidget.btnSelected.connect(self.setVideoSourec)
        self._monitor.configSignal.connect(self.showEnvData)

    def _initListWidget(self):
        # 初始化界面
        # 通过QListWidget的当前item变化来切换QStackedWidget中的序号
        self._listWidget.currentRowChanged.connect(
            self._stackedWidget.setCurrentIndex)
        self._listWidget.currentRowChanged.connect(self._display)
        # 去掉边框
        self._listWidget.setFrameShape(QListWidget.NoFrame)
        # 隐藏滚动条
        self._listWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self._listWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def _mdisplay(self, state, data, datalist, widget, index):
        if not state:
            WarningMessageBox("数据获取失败，服务器异常").exec()
            return
        widget.disPlayGoodsItem(data.get(datalist), refresh=True, data_refresh=True)
        if datalist == "goodsList":
            clsstate, clsdata = self._goodsHandler.showCls()
            if clsstate:
                widget.init_goods_cls(clsdata["cateList"])
                self._displayFlag[index] = 0
            else:
                WarningMessageBox("分类数据获取失败，服务器异常").exec()
                self._displayFlag[index] = 1
        else:
            self._displayFlag[index] = 0

    def _fill_img_count(self, data, slider, content):
        slider_count = data["imagesSlider"].__len__()
        content_count = data["imageContent"].__len__()
        if slider_count < slider:
            for count in range(slider - slider_count):
                data["imagesSlider"].append("请点击插入图片")
        if content_count < content:
            for count in range(content - content_count):
                data["imageContent"].append("请点击插入图片")

    def _display(self, index):
        if index == 1 and  self._displayFlag[index]:
            if self._advertiseWidget.display():
                self._displayFlag[index] = 0

        if index == 2 and self._displayFlag[index]:
            state, data = self._goodsHandler.goods_show()

            if state:
                for each in data["goodsList"]:
                    self._fill_img_count(each, 3, 5)
            self._mdisplay(state, data, "goodsList", self._shopWidget, index)

        elif index == 3 and self._displayFlag[index]:
            state, data = self._activityHandler.activity_show()
            if state:
                for each in data["activityList"]:
                    self._fill_img_count(each, 3, 5)
            self._mdisplay(state, data, "activityList", self._activityWidget, index)

        elif index == 4 and self._displayFlag[index]:
            state, data = self.landHandler.land_show()
            if state:
                for each in data["landList"]:
                    self._fill_img_count(each, 3, 3)
            self._mdisplay(state, data, "landList", self._landWidget, index)

        elif index == 5:
            state1, order = self._orderHandler.get_goods_order()
            state2, group = self._orderHandler.get_group_number_data()

            if state1 and state2:
                self._orderItemDisPlayWidget.updateGoodsOrderData(order["goods_order_list"])
                self._orderItemDisPlayWidget.updateGroupOrderData(group["group_order_count"])
            else:
                WarningMessageBox("数据获取失败，服务器异常").exec()

    def _addItem(self, test):
        item = QListWidgetItem(self._listWidget)
        item.setSizeHint(QSize(80, 60))
        item.setTextAlignment(Qt.AlignCenter)
        item.setFont(QFont("FontAwesome", 14))
        item.setText(test)

    def addWidget(self, widget):
        self._stackedWidget.addWidget(widget)

    def getWidget(self, index):
        return self._stackedWidget.widget(index)

    def setVideoSourec(self, videoid):
        cap = self._capMap.get(videoid[3:])

        if cap is None:
            addr = self._rmtpMap[videoid[3:]]
            self._currentCapName = videoid[3:]
            self.changeAddr.emit(addr)
            self.waitDia.exec()
        else:
            self.showVideo.stop()
            self.setCap.emit(cap)

    def _getCap(self, cap):
        self.showVideo.stop()
        #self._capMap[self._currentCapName] = cap
        self.setCap.emit(cap)

    def _getImgError(self):
        ret = QuestionMessageBox("获取摄像头失败,是否尝试重新获取").exec()
        #del self._capMap[self._currentCapName]
        if ret == QMessageBox.Yes:
            self.setVideoSourec("\uf030  " + self._currentCapName)

    def showEnvData(self, target_time_device):
        dataDeviceId = None

        for each in self._deviceMsg:
            if each["deviceName"] == target_time_device[0][3:]:
                dataDeviceId = each["dataDeviceId"]
        if dataDeviceId is not None:
            state, ret = self._envDataHandle.getEnvData(dataDeviceId, target_time_device[1])
            if state:
                envDataLIst = ret["environment_data_list"]
                tempDisplayData = disPlayData()
                for each in envDataLIst:
                    t = float(each["create_time"].split(" ")[1].replace(':', '.')[:4])
                    tempDisplayData.timex.append(t)
                    tempDisplayData.tempy.append(float(each["temperature"]))
                    tempDisplayData.humidity.append(float(each["humidity"]))
                    tempDisplayData.PM2D5.append(float(each["PM2D5"]))
                    tempDisplayData.lighty.append(1)
                self._monitor.updatePlot(tempDisplayData)
            else:
                WarningMessageBox("数据获取失败，服务器异常").exec()
                return

# 加密
def enctry(s):
    k = 'djq%5cu#-56715abg$z9_i#_w=$o88m!*alpbedlbat8cr74sd'
    encry_str = ""
    for i, j in zip(s, k):
        # i为字符，j为秘钥字符
        temp = str(ord(i) + ord(j)) + '_'  # 加密字符 = 字符的Unicode码 + 秘钥的Unicode码
        encry_str = encry_str + temp
    return encry_str


# 解密
def dectry(p):
    k = 'djq%5cu#-56715abg$z9_i#_w=$o88m!*alpbedlbat8cr74sd'
    dec_str = ""
    for i, j in zip(p.split("_")[:-1], k):
        # i 为加密字符，j为秘钥字符
        temp = chr(int(i) - ord(j))  # 解密字符 = (加密Unicode码字符 - 秘钥字符的Unicode码)的单字节字符
        dec_str = dec_str + temp
    return dec_str

def lgin():
    da = LoginDialog()
    with open("./xpk.txt", "rb") as f:
        pswd = dectry(f.read().decode("utf-8")).split(",")
    if int(pswd[0]):
        da.setRemember(True)
        da.setID(pswd[1])
        da.setPassword(pswd[2])
    else:
        da.setRemember(False)
    if da.exec():
        if da.getID() == "" or da.getPassward() == "":
            WarningMessageBox("用户名、密码不能为空").exec()
            lgin()
        else:
            if da.getID() == "一线生鸡" and da.getPassward() == "123456":
                if da.isRemember():
                    with open("./xpk.txt", "wb") as f:
                        f.write(enctry("1,一线生鸡,123456").encode("utf-8"))
                else:
                    print(da.isRemember())
                    with open("./xpk.txt", "wb") as f:
                        f.write(enctry("0,一线生鸡,123456").encode("utf-8"))
                return 1
            else:
                WarningMessageBox("用户名、密码不正确").exec()
                lgin()
    else:
        sys.exit(0)

if __name__ == '__main__':
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    with open("shopPjt.qss", "r") as f:
        style = f.read()
    app.setStyleSheet(style)
    fontId = QFontDatabase.addApplicationFont(
        "../Data/fontawesome-webfont.ttf")
    lgin()
    w = LeftTabWidget()
    w.show()

    sys.exit(app.exec_())
